// part1:C14:ex14.49.cpp
// class Date.
// an oprator to tranform type to bool.
#include <iostream>
#include <fstream>
class Date
{
public:
    Date();
    Date(int y, int m, int d)
    {
        year = y;
        month = m;
        day = d;
    }
    friend istream& operator>>(istream &is, Date &dt);
    friend bool operator==(const Date &dl, const Date &dr);
    friend bool operator!=(const Date &dl, const Date &dr);
    friend bool operator<(const Date &dl, const Date &dr);
    friend bool operator<=(const Date &dl, const Date &dr);
    friend bool operator>(const Date &dl, const Date &dr);
    friend bool operator>=(const Date &dl, const Date &dr);
    explicit operator bool()
    {
        vector<vector<int>> days_per_month = {
            {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
            {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        };

        return 1 <= month && month <= 12 && 1 <= day && 
          day <= days_per_month[isLeapYear() ? 1 : 0][month - 1];
    }

    bool isLeapYear()
    {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
private:
    int year, month, day;
};

istream& operator>>(istream &is, Date &dt)
{
    is >> dt.year >> dt.month >> dt.day;
    if (!is) 
    {
        dt = Date(0, 0, 0);    
    }
    return is;
}

bool operator==(const Date &dl, const Date &dr)
{
    return dl.year == dr.year && dl.month == dr.month &&
        dl.day == dr.day;
}

bool operator!=(const Date &dl, const Date &dr)
{
    return !(dl == dr);
}

bool operator<(const Date &dl, const Date &dr)
{
    return (dl.year < dr.year) ||
        (dl.year == dr.year && dl.month < dr.month) ||
        (dl.year == dr.year && dl.month == dr.month &&
            dl.day < dr.day);
}

bool operator<=(const Date &dl, const Date &dr)
{
    return (dl < dr) || (dl == dr);
}

bool operator>(const Date &dl, const Date &dr)
{
    return !(dl <= dr);
}

bool operator>=(const Date &dl, const Date &dr)
{
    return (dl > dr) || (dl == dr);
}